package fr.lelouet.stress;

import java.util.List;

/**
 * <p>
 * A stressable represents a usage of a resource. That usage can be configured
 * with values calibrated using tests.
 * </p>
 * <p>
 * The stress should only be started when a call to run() is done, and that call
 * should only exit when a call to stop() is done.
 * </p>
 * <p>
 * The stress tools are assumed to be kept working between the configuration,
 * but the time between a call to {@link #configure(Object)} and the real
 * reconfiguration can be long enough to alter results.<br />
 * A use could be to block the {@link #configure(Object)} untill the
 * configuration is actually used ; But that would potentially lead to huge time
 * losses in cas of several stressers.<br />
 * The chosen the usage is to first configure each stresser, then call
 * {@link #waitCorrectConfiguration()} on each stresser.
 * </p>
 */
public interface Stressable extends Runnable {

	/**
	 * @return a list of correct calibration values for given resource usage.
	 *         This can start and stop itself in order to calibrate values
	 */
	public List<Object> calibrate();

	/**
	 * specify the usage of the resource, using a calibrated object.<br />
	 * Since the configuration is supposed to be in a non-critical loop, we can
	 * afford the casts.<br />
	 * The configuration is not used right after that call : a call to
	 * 
	 * @return was the configuration correct ?
	 * @param configuration
	 *            one object return from the calibrate()
	 */
	public boolean configure(Object configuration);

	/** wait for the last configuration to be applied */
	public void waitCorrectConfiguration();

	/**
	 * Starts the stress. Should exit before a call to stop, even if the stress
	 * is dynamic.<br />
	 * returns at once if this is already being run.
	 */
	@Override
	public void run();

	/**
	 * waits untill the stress is running. Actually, that can return when the
	 * stress is stopped, if there was a crash inside.
	 */
	public void waitForRun();

	/** requires this to stop as soon as possible */
	public void stop();

	/** requires this to stop, wait for the stop, then return. */
	public void stopNow();

}
